package fem2.pre_and_post;

import java.util.ArrayList;

import fem2.MeshGenerator;

public class RefineQuadMeshGenerator extends MeshGenerator {

	private double x0;
	private double y0;
	private double dx;
	private double dy;
	private double alpha;
	private int n;

	/**
	 * 
	 * @param x0
	 *            start x
	 * @param y0
	 *            start y
	 * @param dx
	 *            x stepping
	 * @param dy
	 *            y stepping
	 * @param alpha
	 *            angle of rotation
	 * @param n
	 *            number of generated cell
	 */
	public RefineQuadMeshGenerator(double x0, double y0, double dx, double dy, double alpha, int n) {
		this.x0 = x0;
		this.y0 = y0;
		this.dx = dx;
		this.dy = dy;
		this.alpha = alpha;
		this.n = n;
	}

	@Override
	public ArrayList<double[]> getNodes(int dim) {
		ArrayList<double[]> nodes = new ArrayList<double[]>();

		double c = Math.cos(alpha);
		double s = Math.sin(alpha);

		for (int i = 0; i < n + 1; i++) {
			nodes.add(new double[] { x0 + i * dx * c, y0 + i * dx * s });
			nodes.add(new double[] { x0 - dy * s + i * dx * c, y0 + dy * c + i * dx * s });

			if (i < n) {
				nodes.add(new double[] { x0 + c * (dx / 3) - s * (dy / 2) + i * dx * c,
						y0 + s * (dx / 3) + c * (dy / 2) + i * dx * s });
				nodes.add(new double[] { x0 + c * (2 * dx / 3) - s * (dy / 2) + i * dx * c,
						y0 + s * (2 * dx / 3) + c * (dy / 2) + i * dx * s });

				nodes.add(new double[] { x0 + c * (dx / 3) - s * dy + i * dx * c,
						y0 + s * (dx / 3) + c * dy + i * dx * s });
				nodes.add(new double[] { x0 + c * (2 * dx / 3) - s * dy + i * dx * c,
						y0 + s * (2 * dx / 3) + c * dy + i * dx * s });
			}

		}

		return nodes;
	}

	@Override
	public ArrayList<ArrayList<Integer>> getConnectivities() {
		ArrayList<ArrayList<Integer>> connectivities = new ArrayList<ArrayList<Integer>>();

		int i1 = 0;
		int di = 6;
		for (int i = 0; i < n; i++) {
			int i2 = i1 + 1;
			int i3 = i1 + 2;
			int i4 = i1 + 3;
			int i5 = i1 + 4;
			int i6 = i1 + 5;
			int i7 = i1 + 6;
			int i8 = i1 + 7;

			ArrayList<Integer> e1 = new ArrayList<Integer>();
			e1.add(i1);
			e1.add(i7);
			e1.add(i4);
			e1.add(i3);

			ArrayList<Integer> e2 = new ArrayList<Integer>();
			e2.add(i1);
			e2.add(i3);
			e2.add(i5);
			e2.add(i2);

			ArrayList<Integer> e3 = new ArrayList<Integer>();
			e3.add(i3);
			e3.add(i4);
			e3.add(i6);
			e3.add(i5);

			ArrayList<Integer> e4 = new ArrayList<Integer>();
			e4.add(i4);
			e4.add(i7);
			e4.add(i8);
			e4.add(i6);

			connectivities.add(e1);
			connectivities.add(e2);
			connectivities.add(e3);
			connectivities.add(e4);

			i1 += di;
		}

		return connectivities;
	}

}
